package setting

import (
	"fmt"

	"go.uber.org/zap"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

var AppConf = new(appConfig)

type appConfig struct {
	Mode        string      `mapstructure:"mode"`
	Port        string      `mapstructure:"port"`
	MysqlConfig mysqlConfig `mapstructure:"mysql"`
	RedisConfig redisConfig `mapstructure:"redis"`
	JwtConfig   jwtConfig   `mapstructure:"jwt"`
	LogConfig   logConfig   `mapstructure:"log"`
	ApiConfig   apiConfig   `mapstructure:"api"`
	EmailConfig emailConfig `mapstructure:"email"`
}

type mysqlConfig struct {
	Master dbConfig `mapstructure:"master"`
	Slave  dbConfig `mapstructure:"slave"`
}
type dbConfig struct {
	Ip              string `mapstructure:"ip"`
	Port            string `mapstructure:"port"`
	Database        string `mapstructure:"database"`
	User            string `mapstructure:"user"`
	Password        string `mapstructure:"password"`
	ConnectionLimit uint   `mapstructure:"connectionLimit"`
}

type redisConfig struct {
	Ip       string `mapstructure:"ip"`
	Port     string `mapstructure:"port"`
	Password string `mapstructure:"password"`
	Db       string `mapstructure:"db"`
}

type jwtConfig struct {
	Secret string `mapstructure:"secret"`
}
type logConfig struct {
	Level      string `mapstructure:"level"`
	Filename   string `mapstructure:"filename"`
	Maxsize    uint   `mapstructure:"maxsize"`
	MaxAge     uint   `mapstructure:"maxAge"`
	MaxBackups uint   `mapstructure:"maxBackups"`
}

type apiConf struct {
	Url string `mapstructure:"url"`
	Key string `mapstructure:"key"`
}

type apiConfig struct {
	Tuling   apiConf `mapstructure:"tuling"`
	Tianxing apiConf `mapstructure:"tianxing"`
	Qweather apiConf `mapstructure:"qweather"`
}

type emailConf struct {
	Name     string `mapstructure:"name"`
	Account  string `mapstructure:"account"`
	Password string `mapstructure:"password"`
}

type emailConfig struct {
	ServName         string      `mapstructure:"servName"`
	Host             string      `mapstructure:"host"`
	Port             int         `mapstructure:"port"`
	RecvHost         string      `mapstructure:"recvhost"`
	RecvPort         string      `mapstructure:"recvport"`
	ContentTypeHTML  string      `mapstructure:"contentTypeHTML"`
	ContentTypePlain string      `mapstructure:"contentTypePlain"`
	Sender           emailConf   `mapstructure:"sender"`
	Recipient        []emailConf `mapstructure:"recipient"`
}

//读取配置
func AppSetting() {
	viper.SetConfigFile("./conf/app.yaml") // 指定配置文件
	//viper.AddConfigPath("/gin_template/conf/") // 指定查找配置文件的路径
	err := viper.ReadInConfig() // 读取配置信息
	if err != nil {             // 读取配置信息失败
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}

	//viper.Get()
	//将读取的配置保存到全局变量dbConf
	if err := viper.Unmarshal(AppConf); err != nil {
		panic(fmt.Errorf("unmarshal conf failed, err:%s \n", err))
	}
	//fmt.Println("配置写入成功", AppConf)
	// 监控配置文件变化
	viper.WatchConfig()
	//将发生修改的配置文件写入到全局变量
	viper.OnConfigChange(func(in fsnotify.Event) {
		zap.L().Info("配置文件发生修改...")
		if err := viper.Unmarshal(AppConf); err != nil {
			panic(fmt.Errorf("unmarshal conf failed, err:%s \n", err))
		}
	})
}
